package com.zp.kidshop.common.exception;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;




import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.InvalidResultSetAccessException;

import com.alibaba.fastjson.JSON;
import com.zp.kidshop.common.pojo.ResObj;
import com.zp.kidshop.common.util.LogUtil;
/**
 * 
 * @Title: ExceptionServiceAOPHandler.java
 * @Package com.minghang.common.exception.aop 
 * @Description: 暂时，未使用此类。
 * 		异常，另外拦截，需要Spring
 * @author 张鹏  
 * @date 2017年2月16日 下午2:59:49 
 * @version V1.0
 */
public class ExceptionServiceAOPHandler {
		
	private static final String ERROR_PROCESS_STRING = "请联系程序开发人员处理！";

	public void doBefore(JoinPoint joinPoint) throws ClassNotFoundException {
		LogUtil.addLog(getProcessInfo(joinPoint, "开始").toString());
	}

	public void doAfter(JoinPoint joinPoint) {
		LogUtil.addLog(getProcessInfo(joinPoint, "执行完成").toString());
	}

	public void doAfterReturn(JoinPoint joinPoint, Object result) {
		if (result != null) {
			StringBuffer sbBuffer = getProcessInfo(joinPoint, "执行完成");
			sbBuffer.append("执行返回数据:" + result + "\r\n");
			LogUtil.addLog(sbBuffer.toString());
		}
	}

	public void doAfterThrowing(Throwable e) {
		LogUtil.addLog("执行程序抛出未知异常:" + getTrace(e));
	}

	public Object doAround(ProceedingJoinPoint proceedingJoinPoint)
			throws Throwable {
		LogUtil.addLog("开始执行程序并捕获错误");
		Object result = null;
		try {
			long startTime = System.currentTimeMillis();
			LogUtil.addLog("程序执行开始时间:" + startTime);
			result = proceedingJoinPoint.proceed();
			long endTime = System.currentTimeMillis();
			LogUtil.addLog("程序执行结束时间:" + endTime);
			LogUtil.addLog("程序执行耗时：" + (endTime - startTime) + "毫秒");
		} catch (Exception e) {
			LogUtil.addLog("抛出异常类：" + e.getClass());
			LogUtil.addLog("执行程序：" + getMethodNameAndArgs(proceedingJoinPoint));
			LogUtil.addLog("捕获异常：" + getTrace(e));
			ResObj exceptionResObj = new ResObj();
			if(e instanceof NullPointerException){
				exceptionResObj.setCode("JAVA-ERROR-NullPointerException");
				exceptionResObj.setMsg("执行程序过程中出现空指针！" + ERROR_PROCESS_STRING + "\r\n(" + e.getMessage() + ")");
			}else if(e instanceof SQLClientInfoException){
				exceptionResObj.setCode("JAVA-ERROR-SQLClientInfoException");
				exceptionResObj.setMsg("执行程序过程中连接数据库出错！" + ERROR_PROCESS_STRING + "\r\n(" + e.getMessage() + ")");
			}else if((e instanceof SQLException)||(e instanceof InvalidResultSetAccessException)){
				exceptionResObj.setCode("JAVA-ERROR-SQLException-InvalidResultSetAccessException");
				exceptionResObj.setMsg("执行程序过程中存取数据出错！" + ERROR_PROCESS_STRING + "\r\n(" + e.getMessage() + ")");
			}else if(e instanceof DataIntegrityViolationException){
				exceptionResObj.setCode("JAVA-ERROR-DataIntegrityViolationException");
				exceptionResObj.setMsg("数据库中数据有错,违背的数据完整性约束！" + ERROR_PROCESS_STRING + "\r\n(" + e.getMessage() + ")");
			}else if(e instanceof CannotGetJdbcConnectionException){
				exceptionResObj.setCode("JAVA-ERROR-CannotGetJdbcConnectionException");
				exceptionResObj.setMsg("连接数据库出错！" + ERROR_PROCESS_STRING + "\r\n(" + e.getMessage() + ")");
			}else {
				exceptionResObj.setCode("JAVA-ERROR-ClassNotFoundException");
				exceptionResObj.setMsg("执行程序过程中出现未知错误！" + ERROR_PROCESS_STRING + "\r\n(" + e.getMessage() + ")");
			}
			result = exceptionResObj;
		}
		LogUtil.addLog("返回数据：" + result);
		return result;
	}

	/**
	 * 获取执行信息
	 * 
	 * @param joinPoint
	 * @param processResult
	 * @return
	 */
	protected StringBuffer getProcessInfo(JoinPoint joinPoint,
			String processResult) {
//		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
//				.getRequestAttributes()).getRequest();
		StringBuffer sb = new StringBuffer("请求参数：\r\n");
//		sb.append("IP:" + request.getRemoteAddr() + "\r\n");		
		sb.append(getMethodNameAndArgs(joinPoint) + "\r\n");
		sb.append("执行状况：" + processResult + "\r\n");
		return sb;
	}

	/**
	 * 获取方法名和参数
	 * 
	 * @author 雷端
	 * @param joinPoint
	 * @return
	 */
	private String getMethodNameAndArgs(JoinPoint joinPoint) {
		Object[] args = joinPoint.getArgs();
		StringBuffer sb = new StringBuffer("请求方法：");
		sb.append(joinPoint.getTarget().getClass().getName() + "."
				+ joinPoint.getSignature().getName() + "(");
		for (int i = 0; i < args.length; i++) {
			sb.append("arg[" + i + "]: " + JSON.toJSONString(args[i]) + ",");
		}
		if (args.length > 0) {
			sb.deleteCharAt(sb.length() - 1);
		}
		sb.append(")");
		return sb.toString();
	}	

	/**
	 * 将异常信息输出到LogUtil.addLog文件
	 * 
	 * @param t
	 * @return
	 */
	public static String getTrace(Throwable t) {
		StringWriter stringWriter = new StringWriter();
		PrintWriter writer = new PrintWriter(stringWriter);
		t.printStackTrace(writer);
		StringBuffer buffer = stringWriter.getBuffer();
		return buffer.toString();
	}
}
